package org.ht.demo.openapi.parser;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.ht.demo.openapi.bean.SwMonitor;
import org.ht.demo.openapi.util.DeviceUtils;
import org.ht.demo.openapi.util.FloatUtils;
import org.ht.demo.openapi.util.StringUtil;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List;

public class SwMonitorParser {

    public static List<SwMonitor> parse(String base64UpData, String imei) {
        List<SwMonitor> swMonitorList = new ArrayList<>();

        if (StringUtil.isNotNullStr(base64UpData)) {
            String hexUpData = StringUtil.base64StrToHexStr(base64UpData);
            String fragmentTypeBinary = StringUtil.hexString2binaryString(DeviceUtils.buileWei(hexUpData, 1, 0));//帧类型
            Integer command = Integer.parseInt(fragmentTypeBinary.substring(0, 6), 2);//指令
            Integer error = Integer.parseInt(fragmentTypeBinary.substring(0, 7), 2);//错误类型, 0:正常,1:数据溢出,2:读写错误

            //序号, 主动数据上报，序号为0，非0：服务器端发起指令
            Integer serialNumber = Integer.parseInt(
                    DeviceUtils.buileWei(hexUpData, 2, 3),
                    16);

            if (command == 0 && serialNumber == 0 && error == 0) {
                String fragmentStatus = DeviceUtils.buileWei(hexUpData, 4, 0);//帧状态
                Integer voltage = Integer.parseInt(DeviceUtils.buileWei(hexUpData, 5, 0), 16);//电量
                Integer rsrp = Integer.parseInt(DeviceUtils.buileWei(hexUpData, 6, 0), 16);//信号强度
                Integer recordNum = Integer.parseInt(DeviceUtils.buileWei(hexUpData, 7, 0), 16);//记录数

                int recordIndex = 8; //记录读取位置，起始位置为第8个字节
                final int gwsIndexOfRecord = 5; //记录中工位数的位置
                final int timeLengthOfRecord = 4; //记录中时间的长度（字节）
                final int warnOfRecord = 1; //记录中报警状态的长度（字节）
                final int gwsOfRecord = 1; //记录中工位数的长度（字节）
//                int readIndex = 0;//数据的读取位置
                for (int i = 0; i < recordNum; i++) {
                    //当前记录的工位数
                    int gws = Integer.parseInt(DeviceUtils.buileWei(hexUpData, recordIndex + gwsIndexOfRecord, 0), 16);
                    String tims = DeviceUtils.buileWei(hexUpData, recordIndex, recordIndex +3);
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    DateTime cotime= DateTime.parse(aesTime(tims), DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")).plusHours(8);


                    //读取位置移动到工位数据的开始位置
                    recordIndex = recordIndex + timeLengthOfRecord + warnOfRecord + gwsOfRecord;

                    for (int j = 0; j < gws; j++) {
                        String alarm = DeviceUtils.buileWei(hexUpData, recordIndex, 0);
                        recordIndex = recordIndex + 1;//向右移动1个字节，读取单位
                        String unit = DeviceUtils.buileWei(hexUpData, recordIndex, 0);
                        recordIndex = recordIndex + 1;//向右移动1个字节，读取数据
                        String value = DeviceUtils.buileWei(hexUpData, recordIndex, recordIndex + 3);
                        recordIndex = recordIndex + 3;//读完取数据，向右移动4个字节

//                        0000 0001  失效
//                        0000 0010  Alarm Dowm
//                        0000 0100  Alarm Up
//                        0000 1000  Alarm Delta

                        SwMonitor swMonitor = new SwMonitor();
//                        8:差值过大，4:高于上限，2:低于下限，1:传感器故障
                        swMonitor.setCollectiontime(cotime.toDate());
                        swMonitor.setWpstatus(0);
                        swMonitor.setWrstatus(0);
                        if (StringUtil.isEqual(alarm, "08")) {//differ
                            swMonitor.setWrstatus(1);
                        }else if(StringUtil.isEqual(alarm, "04")) {//over
                            swMonitor.setWpstatus(2);//过压
                        }else if(StringUtil.isEqual(alarm, "02")) {//under
                            swMonitor.setWpstatus(1);//欠压
                        }else if(StringUtil.isEqual(alarm, "01")) {//lost
                            swMonitor.setWpstatus(4);
                        }


                        if (StringUtil.isEqual(unit, "00")) {//M
                            swMonitor.setType(6);
                            swMonitor.setCodetype("SW");
                            swMonitor.setMonitorname("水位");
                            swMonitor.setDataunit("米");
                            swMonitor.setData(String.format("%.2f", FloatUtils.base64ToFloat(value, false,2)));
                        }

                        if (StringUtil.isEqual(unit, "01")) {//KPa
                            swMonitor.setType(5);
                            swMonitor.setCodetype("SY");
                            swMonitor.setMonitorname("水压");
                            swMonitor.setDataunit("KPa");
                            swMonitor.setData(String.format("%.2f",FloatUtils.base64ToFloat(value, false,2)));
                        }

                        if (StringUtil.isEqual(unit, "02")) {//MPa
                            swMonitor.setType(5);
                            swMonitor.setCodetype("SY");
                            swMonitor.setMonitorname("水压");
                            swMonitor.setDataunit("MPa");
                            swMonitor.setData(String.format("%.2f",FloatUtils.base64ToFloat(value, false,2)));
                        }

                        if (StringUtil.isEqual(unit, "05")) {//bar 1bar = 0.1Mpa
                            swMonitor.setType(5);
                            swMonitor.setCodetype("SY");
                            swMonitor.setMonitorname("水压");
                            swMonitor.setDataunit("Mpa");
                            swMonitor.setData(String.format("%.2f",FloatUtils.base64ToFloat(value, false,2) * 0.1f));
                        }

                        swMonitor.setBatterys(1);
                        swMonitor.setVoltagevalue(voltage);
                        swMonitor.setDsignal(rsrp);
                        swMonitor.setImei(imei);
                        swMonitor.setMac(imei);

                        //log.warn("sw-v1:" + swMonitor.toString());

                        swMonitorList.add(swMonitor);
                    }
                    recordIndex = recordIndex + 1;//读完记录中的工位数据，向右移动1个字节，读取下一条记录

                }
            }

        }
        return swMonitorList;
    }


    public static String aesTime(String ast){
        byte[] data= StringUtil.parseHexStr2Byte(ast);
        System.out.println(Byte.toUnsignedInt(data[2]));
        int year = Byte.toUnsignedInt(data[3])>> 2;
        int month = ((Byte.toUnsignedInt(data[3]) & 0x03) << 2) + (Byte.toUnsignedInt(data[2]) >> 6);
        int day = (Byte.toUnsignedInt(data[2]) >> 1) & 0x1f;
        int hour = ((Byte.toUnsignedInt(data[2]) & 0x01) << 4) + (Byte.toUnsignedInt(data[1]) >> 4);
        int minute = ((Byte.toUnsignedInt(data[1]) & 0x0f) << 2) + (Byte.toUnsignedInt(data[0]) >> 6);
        int second = (Byte.toUnsignedInt(data[0]) & 0x3f);
        return String.format("20%d-%02d-%02d %02d:%02d:%02d",year,month,day,hour,minute,second);
    }



}
